package com.shinbada.modules.sys.web;

import com.shinbada.common.Common;
import com.shinbada.common.json.AjaxJson;
import com.shinbada.common.utils.StringUtils;
import com.shinbada.config.properties.ShinProperites;
import com.shinbada.core.persistence.Page;
import com.shinbada.core.web.BaseController;
import com.shinbada.modules.sys.entity.Role;
import com.shinbada.modules.sys.entity.User;
import com.shinbada.modules.sys.service.RoleService;
import com.shinbada.modules.sys.service.UserService;
import com.shinbada.modules.sys.utils.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 角色Controller
 *
 * @author initcap
 * @version 2016-12-05
 */
@RestController
@RequestMapping("/sys/role")
@Api(tags = "角色管理")
public class RoleController extends BaseController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    @ModelAttribute("role")
    public Role get(@RequestParam(required = false) String id) {
        if (StringUtils.isNotBlank(id)) {
            return roleService.get(id);
        } else {
            return new Role();
        }
    }

    @RequiresPermissions("user")
    @GetMapping("list")
    @ApiOperation("获取角色集合")
    public AjaxJson data(Role role, HttpServletRequest request, HttpServletResponse response) {
        Page<Role> page = roleService.findPage(new Page<>(request, response), role);
        return AjaxJson.success().put("page", page);
    }


    @RequiresPermissions(value = {"sys:role:view", "sys:role:add", "sys:role:edit"}, logical = Logical.OR)
    @GetMapping("queryById")
    @ApiOperation("根据主键进行查询")
    public AjaxJson queryById(Role role) {

        String newDataRuleIds = "";
        if (role != null) {
            if (StringUtils.isNotBlank(role.getDataRuleIds())) {
                for (String id : role.getDataRuleIds().split(Common.Dict.PLATFORM_SPLIT_SEPARATOR)) {
                    newDataRuleIds = newDataRuleIds + "dataRule-" + id + ",";
                }
            }
            if (newDataRuleIds.length() > 1) {
                role.setDataRuleIds(newDataRuleIds.substring(0, newDataRuleIds.length() - 1));
            }
            role.setMenuIdList(roleService.queryAllNotChildrenMenuId(role.getId()));
        }


        return AjaxJson.success().put("role", role);
    }


    @RequiresPermissions(value = {"sys:role:assign", "sys:role:auth", "sys:role:add", "sys:role:edit"}, logical = Logical.OR)
    @PostMapping("save")
    @ApiOperation("保存角色数据")
    public AjaxJson save(Role role) {
        if (shinProperites.isDemoMode()) {
            return AjaxJson.error("演示模式，不允许操作！");
        }
        Role old = roleService.get(role.getId());
        if (old == null) {
            // 添加数据，如果是超级管理员添加的，那么算作系统数据，普通人不可以变更
            if (UserUtils.getUser().isAdmin()) {
                role.setSysData(ShinProperites.YES);
            } else {
                role.setSysData(ShinProperites.NO);
            }
        } else if (!UserUtils.getUser().isAdmin() && ShinProperites.YES.equals(old.getSysData())) {
            return AjaxJson.error("越权操作，系统数据不能修改！");
        }
        /**
         * 后台hibernate-validation插件校验
         */
        String errMsg = beanValidator(role);
        if (StringUtils.isNotBlank(errMsg)) {
            return AjaxJson.error(errMsg);
        }
        if (!Common.Flowable.FLOWABLE_STRING_TRUE.equals(checkName(role.getOldName(), role.getName()))) {
            return AjaxJson.error("保存角色'" + role.getName() + "'失败, 角色名已存在");
        }
        if (StringUtils.isNotBlank(role.getDataRuleIds())) {
            String dataRuleIds = role.getDataRuleIds();
            String newDataRuleIds = "";
            String[] ruleIds = dataRuleIds.split(",");
            for (String ruleId : ruleIds) {
                if (ruleId.startsWith("dataRule-")) {
                    newDataRuleIds = newDataRuleIds + ruleId.substring(9) + ",";
                }
            }
            if (newDataRuleIds.length() > 1) {
                role.setDataRuleIds(newDataRuleIds.substring(0, newDataRuleIds.length() - 1));
            }
        }
        roleService.saveRole(role);
        return AjaxJson.success("保存角色'" + role.getName() + "'成功");
    }

    @RequiresPermissions("sys:role:del")
    @DeleteMapping("delete")
    @ApiOperation("删除角色")
    public AjaxJson delete(String ids) {
        if (shinProperites.isDemoMode()) {
            return AjaxJson.error("演示模式，不允许操作！");
        }
        StringBuffer msg = new StringBuffer();
        for (String id : ids.split(Common.Dict.PLATFORM_SPLIT_SEPARATOR)) {
            Role role = roleService.get(id);
            if (!UserUtils.getUser().isAdmin() && role.getSysData().equals(ShinProperites.YES)) {
                msg.append("越权操作，只有超级管理员才能修改[" + role.getName() + "]数据！<br/>");
            } else {
                roleService.deleteRole(role);
                msg.append("删除角色[" + role.getName() + "]成功<br/>");

            }
        }
        return AjaxJson.success(msg.toString());
    }

    @RequiresPermissions("sys:role:assign")
    @GetMapping("assign")
    @ApiOperation("获取所属角色用户")
    public AjaxJson assign(User user, HttpServletRequest request, HttpServletResponse response) {
        Page<User> page = userService.findPage(new Page<>(request, response), user);
        return AjaxJson.success().put("page", page);
    }

    @RequiresPermissions("sys:role:assign")
    @DeleteMapping("outrole")
    @ApiOperation("角色分配 -- 从角色中移除用户")
    public AjaxJson outrole(String userId, String roleId) {
        if (shinProperites.isDemoMode()) {
            return AjaxJson.error("演示模式，不允许操作！");
        }
        Role role = roleService.get(roleId);
        User user = userService.get(userId);
        if (UserUtils.getUser().getId().equals(userId) && !UserUtils.getUser().isAdmin()) {
            return AjaxJson.error("无法从角色【" + role.getName() + "】中移除用户【" + user.getName() + "】自己！");
        } else {
            if (user.getRoleList().size() <= 1) {
                return AjaxJson.error("用户【" + user.getName() + "】从角色【" + role.getName() + "】中移除失败！这已经是该用户的唯一角色，不能移除。");
            } else {
                Boolean flag = roleService.outUserInRole(role, user);
                if (!flag) {
                    return AjaxJson.error("用户【" + user.getName() + "】从角色【" + role.getName() + "】中移除失败！");
                } else {
                    return AjaxJson.success("用户【" + user.getName() + "】从角色【" + role.getName() + "】中移除成功！");
                }
            }
        }
    }

    @RequiresPermissions("sys:role:assign")
    @PostMapping("assignrole")
    @ApiOperation("角色分配")
    public AjaxJson assignRole(Role role, String[] ids) {
        if (shinProperites.isDemoMode()) {
            return AjaxJson.error("演示模式，不允许操作！");
        }
        StringBuilder msg = new StringBuilder();
        int newNum = 0;
        for (int i = 0; i < ids.length; i++) {
            User user = roleService.assignUserToRole(role, userService.get(ids[i]));
            if (null != user) {
                msg.append("<br/>新增用户【" + user.getName() + "】到角色【" + role.getName() + "】！");
                newNum++;
            }
        }
        return AjaxJson.success("已成功分配 " + newNum + " 个用户" + msg);
    }

    /**
     * 验证角色名是否有效
     *
     * @param oldName 原来名称
     * @param name    新名字
     * @return 结果
     */
    private String checkName(String oldName, String name) {
        if (name != null && name.equals(oldName)) {
            return "true";
        } else if (name != null && roleService.getRoleByName(name) == null) {
            return "true";
        }
        return "false";
    }


}
